package org.invigorare.auctions.data;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.invigorare.auctions.R;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

/**
 * A wrapper class for shared Application Settings.
 * @author Jeff Chern
 *
 */
public class AppSettings {

	public static final String APP_SETTINGS_SHAREDPREFS = "APP_SETTINGS";

	/* Names of Keys in the Shared Prefs */
	public static final String SETTINGS_OK = "SETTINGS_VERIFIED";
	public static final String WEBSERVICE_URL = "WEBSERVICE_URL";
	public static final String EMPLOYEE_ID = "EMPLOYEE_ID";
	
	public static final String MARKET_NAME = "MARKET_NAME";
	public static final String EMPLOYEE_NAME = "EMPLOYEE_NAME";
	public static final String LAST_SYNC = "LAST_SYNC_TIME";
	
	public static final String FEE_UNLOAD = SaleDataOpener.FEE_UNLOAD;
	public static final String FEE_CLEAN = SaleDataOpener.FEE_CLEAN;
	public static final String FEE_WEIGH = SaleDataOpener.FEE_WEIGH;
	public static final String FEE_PACK = SaleDataOpener.FEE_PACK;
	public static final String FEE_STITCH = SaleDataOpener.FEE_STITCH;
	public static final String FEE_LOAD = SaleDataOpener.FEE_LOAD;
	public static final String COMMISSION_AGENT = SaleDataOpener.COMMISSION_AGENT;
	public static final String COMMISSION_MANDI = SaleDataOpener.COMMISSION_MANDI;
	
	public static final String[] FEES_COMMISSION_FIELDS = new String[] {
		FEE_UNLOAD, FEE_CLEAN, FEE_WEIGH, FEE_PACK, FEE_STITCH, FEE_LOAD, COMMISSION_AGENT, COMMISSION_MANDI 
	};
	
	Context context;
	SharedPreferences settings;
	public AppSettings(Context context) {
		this.context = context;
		this.settings = getSettings(context);
	}
	
	private static SharedPreferences getSettings(Context context) {
		return context.getSharedPreferences(APP_SETTINGS_SHAREDPREFS, Context.MODE_PRIVATE);
	}

	/**
	 * Returns whether this is the first time launching this application,
	 * according to the SharedPreferences.
	 * @param context
	 * @return
	 */
	public synchronized boolean settingsVerified() {
		return settings.getBoolean(SETTINGS_OK, true);
	}
	
	public synchronized String getWebserviceURL() {
		String defaultWebserviceUrl = context.getString(R.string.defaultSyncServerURL);
		return settings.getString(WEBSERVICE_URL, defaultWebserviceUrl);
	}
	
	public synchronized String getEmployeeId() {
		return settings.getString(EMPLOYEE_ID, "");
	}
	
	public synchronized String getEmployeeName() {
		return settings.getString(EMPLOYEE_NAME, "");
	}
	
	public synchronized String getMarketName() {
		return settings.getString(MARKET_NAME, "");
	}
	
	public synchronized long getLastSyncTime() {
		return settings.getLong(LAST_SYNC, 0);
	}
	
	/**
	 * Returns a Map of all fees and commissions for this Mandi,
	 * defaulting to 0 if un-configured.
	 * @return
	 */
	public synchronized Map<String, Float> getCommissionsAndFees() {
		HashMap<String, Float> map = new HashMap<String, Float>();
		
		for (String key : FEES_COMMISSION_FIELDS) {
			map.put(key, settings.getFloat(key, 0));
		}
		
		return map;
	}
	
	/**
	 * Saves user-configurable settings, and marks this as 'first launch' i.e. settings not verified.
	 * @param webserviceUrl
	 * @param employeeId
	 * @return success or failure
	 */
	public synchronized boolean saveUserSettings(String webserviceUrl, String employeeId) {
		SharedPreferences.Editor edit = settings.edit();
		edit.putString(WEBSERVICE_URL, webserviceUrl);
		edit.putString(EMPLOYEE_ID, employeeId);
		edit.putBoolean(SETTINGS_OK, true); // mark 'first_lauch' i.e. settings not verified if any settings change
		
		boolean success = edit.commit(); // use commit() if you need a success or failure report; use apply() if you want to use this from the main thread and have API Level 9+
		Log.v("AppSettings", "user settings -- commit " + (success ? "succeeded" : "failed!"));
		return success;
	}
	
	/**
	 * Saves web-synchronized application settings.
	 * @param mandiName
	 * @param employeeName
	 * @param feeMap
	 * @param syncTime
	 * @return success or failure
	 */
	public synchronized boolean updateAppSettings(String mandiName, String employeeName, Map<String, Float> feeMap, long syncTime) {
		SharedPreferences.Editor edit = settings.edit();
		edit.putString(MARKET_NAME, mandiName);
		edit.putString(EMPLOYEE_NAME, employeeName);
		edit.putLong(LAST_SYNC, syncTime);
		edit.putBoolean(SETTINGS_OK, false); // we consider the program to be successfully configured henceforth.
		
		Set<Entry<String, Float>> feeEntries = feeMap.entrySet();
		for (Map.Entry<String, Float> entry: feeEntries ) {
			edit.putFloat(entry.getKey(), entry.getValue());
		}
		
		boolean success = edit.commit(); // if the commit failed, then the "FIRST_LAUNCH == false" key won't be committed either.
		Log.v("AppSettings", "app settings -- commit " + (success ? "succeeded" : "failed!"));
		return success;
	}
	
}
